package cn.school.controller.student;

import cn.hutool.core.date.DateUtil;
import cn.school.basics.vo.DormitoryBerthVO;
import cn.school.basics.vo.DormitoryExcelVo;
import cn.school.classManage.vo.SchoolClassVO;
import cn.school.common.api.CommonPage;
import cn.school.common.api.CommonResult;
import cn.school.common.exception.ApiException;
import cn.school.controller.test.FileUploadUtils;
import cn.school.controller.test.Result;
import cn.school.educational.vo.SubjectExcelVo;
import cn.school.student.entity.StudentInfo;
import cn.school.student.entity.vo.DeviceStudentExcel;
import cn.school.student.entity.vo.StudentInfoExcel;
import cn.school.student.param.StudentInfoPageParam;
import cn.school.student.param.StudentQueryByClassDTO;
import cn.school.student.service.StudentInfoService;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author yuanyuan
 */
@RestController
@Api(tags = "StudentInfo => 学员信息管理")
@RequestMapping("/student/info")
public class StudentInfoController {

    @Autowired
    private StudentInfoService studentInfoService;
    @Resource
    private FileUploadUtils fileUploadUtils;
    @Value("${student.picturePathDir}")
    private String filePath;


    @ApiOperation("录入学员信息")
    @PostMapping("/enter")
    public CommonResult<Long> enterStudentInfo(@RequestBody StudentInfo studentInfo){
        return studentInfoService.enterStudent(studentInfo);
    }

    @ApiOperation("根据id查询学员信息")
    @GetMapping("/get/{id}")
    public CommonResult<StudentInfo> getStudentInfoById(@PathVariable Long id){
        return studentInfoService.getStudentInfoById(id);
    }

    @ApiOperation("查询所有班级")
    @PostMapping("/allClass")
    public CommonResult<List<SchoolClassVO>> allClass(){
        List<SchoolClassVO> classVOList = studentInfoService.allSchoolClass();
        return CommonResult.success(classVOList);
    }

    @ApiOperation("转班")
    @PostMapping("/zhuanClass")
    public CommonResult<Integer> zhuanClass(@RequestBody StudentInfo studentInfo){
        return studentInfoService.updateByStudentId(studentInfo);
    }

    @ApiOperation("根据id删除学员信息")
    @DeleteMapping("/delete/{id}")
    public CommonResult<Integer> deleteStudentInfo(@PathVariable Long id){
        return studentInfoService.deleteStudentInfo(id);
    }

    @ApiOperation("修改学员信息")
    @PutMapping("/update")
    public CommonResult<Integer> updateStudent(@RequestBody StudentInfo studentInfo){
        return studentInfoService.updateStudent(studentInfo);
    }

    @ApiOperation("批量修改学员信息")
    @PutMapping("/updateBatch")
    public CommonResult<Integer> updateBatchStudent(@RequestBody List<StudentInfo> list){
        return studentInfoService.updateBatchStudent(list);
    }

    @ApiOperation("分页查询学员信息")
    @PostMapping("/page")
    public CommonResult<CommonPage<StudentInfo>> getStudentInfoPage(@RequestBody(required = false) StudentInfoPageParam param){
        return studentInfoService.getStudentInfoPage(param);
    }



    @ApiOperation("从excel导入学员信息")
    @PostMapping("/import/excel")
    public CommonResult<Integer> importStudentFromExcel(@RequestParam("file") MultipartFile multipartFile) throws IOException, ApiException {
        return studentInfoService.importStudentInfoFromExcel(multipartFile);
    }

    @ApiOperation("从excel导入学员照片信息")
    @PostMapping("/pictureImport/excel")
    public CommonResult<Integer> importStudentPictureExcel(@RequestParam("file") MultipartFile multipartFile) throws IOException{
        return studentInfoService.importStudentPictureExcel(multipartFile);
    }

    @ApiOperation("根据班级查询学员信息")
    @PostMapping("/findByClass")
    public CommonResult<CommonPage<StudentInfo>> findStudentInfoByClass(@RequestBody StudentQueryByClassDTO queryDTO){
        IPage<StudentInfo> pageList = studentInfoService.findStudentInfoByClass(queryDTO);
        return CommonResult.success(CommonPage.restPage(pageList));
    }

    @GetMapping("/findStudentListByClassId/{classId}")
    public CommonResult<List<StudentInfo>> findStudentListByClassId(@PathVariable Long classId){
        List<StudentInfo> studentListByClassId = studentInfoService.findStudentListByClassId(classId);
        return CommonResult.success(studentListByClassId);
    }
    @GetMapping("/listByClass/{classId}")
    public CommonResult<List<StudentInfo>> listByClass(@PathVariable String classId){
        List<StudentInfo> list =  studentInfoService.listByClass(classId);
        return CommonResult.success(list);
    }

    @ApiOperation("根据学生id,重置学生的密码")
    @PostMapping("/resetPwd/{id}")
    public CommonResult<String> resetPwd(@PathVariable Long id){
        studentInfoService.resetPwd(id);
        return CommonResult.success("重置成功！");
    }

    @ApiOperation("根据学生ID, 重置监护人密码信息")
    @PostMapping("/parent/resetPwd/{id}")
    public CommonResult<String> parentResetPwd(@PathVariable Long id){
        studentInfoService.parentResetPwd(id);
        return CommonResult.success("重置成功！");
    }

    @ApiOperation("查询班级专业的学费")
    @GetMapping("/findTuitionFee/{classId}")
    public CommonResult<String> findTuitionFeeByClassId(@PathVariable("classId") Long classId){
        String amount = studentInfoService.findTuitionFeeByClassId(classId);
        return CommonResult.success(amount);
    }

    @ApiOperation("批量删除学员信息")
    @PostMapping("/deleteBatchStudentInfo")
    public CommonResult<Integer> deleteBatchStudentInfo(@RequestBody List<StudentInfo> list) {
        int num = studentInfoService.deleteBatchStudentInfo(list);
        if (num > 0) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation("批量重置学生密码")
    @PostMapping("/batchResetStudentsPwd")
    public CommonResult<Integer> batchResetStudentsPwd(@RequestBody List<StudentInfo> list) {
        int result = studentInfoService.batchResetStudentsPwd(list);
        if (result > 0) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation("批量重置监护人密码")
    @PostMapping("/batchResetParentsPwd")
    public CommonResult<Integer> batchResetParentsPwd(@RequestBody List<StudentInfo> list) {
        int result = studentInfoService.batchResetParentsPwd(list);
        if (result > 0) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation("上传文件")
    @PostMapping("/uploadImage")
    public Result<String> uploadImage(MultipartFile file) throws IOException {
        return fileUploadUtils.upload(file, filePath);
    }

    @ApiOperation("导出学生信息")
    @GetMapping("/excel/exportStudent")
    public void importStudent(HttpServletResponse response, StudentInfo studentInfo) throws IOException {
        //查询学生信息
        List<StudentInfoExcel> studentInfoExcels = studentInfoService.studentByTenantIdExportList(studentInfo);
        EasyExcel.write(response.getOutputStream(), StudentInfoExcel.class).sheet("学生信息").doWrite(studentInfoExcels);
    }

    @GetMapping("/excel/importTemplate")
    public CommonResult<String> importTemplate(HttpServletResponse response, StudentInfo studentInfo) throws IOException {
        //查询全部数据
        String timeDir = DateUtil.format(new Date(),"yyyyMMddHHmmss");
        String dirPath = filePath + DateUtil.today()+File.separator+timeDir;
        File file = new File(dirPath);
        //创建文件夹，准备打包zip
        if(!file.isDirectory()){
            file.mkdirs();
        }
        String fileName = dirPath +"/student.xlsx";
        List<DeviceStudentExcel> studentAll = studentInfoService.findStudentAll(studentInfo);
        EasyExcel.write(fileName, DeviceStudentExcel.class).sheet("学生信息").doWrite(studentAll);
        //将照片复制到excel所在的文件加中
        for (DeviceStudentExcel deviceStudentExcel : studentAll) {
            if(StringUtils.isEmpty(deviceStudentExcel.getImageName())){
                continue;
            }
            InputStream input = null;
            OutputStream output = null;
            try {
                File source = new File(filePath+deviceStudentExcel.getStudentPicture());
                String distFile = deviceStudentExcel.getImageName().substring(deviceStudentExcel.getImageName().indexOf("/")+1);
                File dest = new File(dirPath+File.separator+distFile);
                if(!dest.exists()){
                    dest.createNewFile();
                }
                input = new FileInputStream(source);
                output = new FileOutputStream(dest);
                byte[] buf = new byte[1024];
                int bytesRead;
                while ((bytesRead = input.read(buf)) > 0) {
                    output.write(buf, 0, bytesRead);
                }
            }catch (Exception e){
                e.printStackTrace();
            } finally{
                input.close();
                output.close();
            }

        }
        //将文件夹压缩

        String zip = zip(timeDir, dirPath);
        return CommonResult.success(zip);
    }

    private String zip(String timeDir, String dirPath) {
        String zipFileName = filePath + DateUtil.today() +File.separator+"deviceImageAndData.zip";
        String folderToCompress = dirPath;

        try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName))) {
            // 压缩文件夹
            compressFolder(folderToCompress, timeDir, zipOutputStream);

            System.out.println("Folder compressed successfully!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return DateUtil.today() +File.separator+"deviceImageAndData.zip";
    }

    private static void compressFolder(String sourceFolder, String folderName, ZipOutputStream zipOutputStream) throws IOException {
        File folder = new File(sourceFolder);
        File[] files = folder.listFiles();

        if (files != null) {
            for (File file : files) {
                // 压缩文件
                addToZipFile(folderName + "/" + file.getName(), file.getAbsolutePath(), zipOutputStream);
            }
        }
    }

    private static void addToZipFile(String fileName, String fileAbsolutePath, ZipOutputStream zipOutputStream) throws IOException {
        // 创建ZipEntry对象并设置文件名
        ZipEntry entry = new ZipEntry(fileName);
        zipOutputStream.putNextEntry(entry);

        // 读取文件内容并写入Zip文件
        try (FileInputStream fileInputStream = new FileInputStream(fileAbsolutePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, bytesRead);
            }
        }

        // 完成当前文件的压缩
        zipOutputStream.closeEntry();
    }


    @ApiOperation("学生退宿")
    @PostMapping("/studentRetreat")
    public CommonResult studentRetreat(@RequestBody DormitoryBerthVO vo) {
        int result = studentInfoService.studentRetreat(vo);
        if (result > 0) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }
}
